#include "head.h"


int main(int argc, char* argv[]) 
{

    //初始化线信息结构体
    status_t status;
    init_status(&status, 4);
    if(initLog(1024)){
        fprintf(stderr, "日志文件初始化成功\n");
    }


    //初始化线程池
    init_thread_pool(&status);
    DEBUG_LOG("Thread pool init...");    

    //初始化tcp连接--即socket对象
    int socket_fd;
    //读配置文件
    char* ip = parseINI("ip", NULL);
    printf("%s\n", ip);
    init_socket(&socket_fd, ip, "8080");

    //初始化epoll对象，并将scoket对象加入监听
    int epoll_fd = epoll_create(1);
    add_epoll(epoll_fd, socket_fd);

    conn_t active_list[1024];
    memset(active_list, -1, sizeof(active_list));
    int index = 0;

    MYSQL* mysql_conn;
    if(!init_mysql(&mysql_conn)){
        ERROR_LOG("Error code: %d : %s", ERROR1, mysql_error(mysql_conn));
    }

    while(1){

        struct epoll_event ready_list[1024];
        memset(ready_list, 0, sizeof(ready_list));

        int epoll_num = epoll_wait(epoll_fd, ready_list, 1024, 1);
        if(epoll_num == -1){

            ERROR_LOG("Error code: %d epoll_wait failed.", ERROR1);
        }

        for(int i = 0; i < epoll_num; i++){

            int fd = ready_list[i].data.fd;

            if(fd == socket_fd){

                int net_fd = accept(socket_fd, NULL, NULL);
                if(net_fd == -1){

                    ERROR_LOG("Error code: %d accept.", ERROR1);
                }

                active_list[index].net_fd = net_fd;
                time(&active_list[index].last_time);
                index++;

                if( add_epoll(epoll_fd, net_fd)){
                    ERROR_LOG("Error code: %d add epoll failed.", ERROR1);
                }
            }else{


                for(int i = 0; i < index; i++){
                    if(fd == active_list[i].net_fd){
                        time(&active_list[i].last_time);
                        break;
                    }
                }

                int instruction = -1;
                recv(fd, &instruction, sizeof(int), 0);

                switch(instruction){
                case LOGIN:
                    validate_login(fd, mysql_conn);
                    break;
                case REGIST:
                    register_user(fd, mysql_conn);
                    break;
                case CD:
                    cdServe(fd, mysql_conn);
                    break;
                case LS:
                    lsServe(fd, mysql_conn);
                    break;
                case MKDIR:
                    mkdirServe(fd, mysql_conn);
                    break;
                case RM:

                    rmServe(fd, mysql_conn);
                    break;
                case PUTS: case GETS:

                    for(int i = 0; i < index; i++){
                        if(fd == active_list[i].net_fd){
                            active_list[i].net_fd = 0;
                            break;
                        }
                    }
                    printf("%d\n",fd);
                    pthread_mutex_lock(&status.lock);
                    enqueue(&status.q, fd);
                    pthread_cond_signal(&status.cond);
                    pthread_mutex_unlock(&status.lock);

                    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
                    break;
                case LOGOUT:
                    logout_user(fd, mysql_conn);
                    break;
                }
            }
        }

        for(int i = 0; i < index; i++){

            time_t now;
            time(&now);
            if(active_list[i].net_fd != -1 && now - active_list[i].last_time >= 30){
                printf("超时剔除\n");
                close(active_list[i].net_fd);

                active_list[i].net_fd = -1;
                epoll_ctl(epoll_fd, EPOLL_CTL_DEL, active_list[i].net_fd, NULL);
            }
        }

    }
    return 0;
}

